// 1.函数
/**
 * 1.函数定义
 * 2.函数声明
 * 格式、位置、省写、extern
 * 3.函数调用
 * 4.函数参数
 * (练习变量交换)
 * 传值调用
 *    变量交换：中间变量、+-运算、异或运算
 *    一个数异或本身等于0；任意一个数异或0还等于这个数
 * 指针调用
 *    传指针，通过*取值
 * 引用调用
 * 5.参数的默认值
 * 6.lambda函数
 *  语法
 *  作为函数参数使用 functional、 std::function<return_type(p_type,p_type,...)> const
 *  作为赋值语言右值使用
 *  省写
 *  capture []、[=]、[&z]、[=,&x]、[&,x]
 *  this使用 
 *      [this]  引用调用，可以修改成员
 *      [*this] 传值调用需要c++17才能用
 *  lambda函数作为成员属性时，成员属性无法用auto推导。
 * 
*/
#include <iostream>
// void test(int, int);
#include <functional>

void pre_add(int &, std::function<void(void)> const);

void test(int a, int b = 10)
{
  std::cout << "a : " << a << "\n"
            << "b : " << b << std::endl;
}

int main(void)
{
  // test(1, 2);
  // test(1); // error: too few arguments to function 'void test(int, int)'

  // test(1);

  std::cout << "--------------lambda函数使用---------------" << std::endl;

  // 作为赋值语句右值使用

  // auto
  const std::function<void(void)> add = []() -> void
  {
    static int a = 1;
    a += 2;
    std::cout << "a : " << a << std::endl;
  };

  add();
  // add();
  int c = 0;
  // 作为参数传入使用
  pre_add(c, add);

  // 自执行， 无参、无返回值省写
  []
  {
    std::cout << "test" << std::endl;
  }();

  // -----------capture-------------

  int num0 = 10;
  int num1 = 1;

  [=, &num0]
  {
    num0 *= 2;
    std::cout << "num0 : " << num0 << "\n"
              << "num1 : " << num1 << std::endl;
  }();

  // [this]{
  //   // this->
  // }();

  // [*this]{
  //   // *this.
  // }();

  printf("----------end-----------\n");
}

// void test(int a, int b = 10)
// {
//   std::cout << "a : " << a << "\n"
//             << "b : " << b << std::endl;
// }

void pre_add(int &x, std::function<void(void)> const func = NULL)
{
  std::cout << "x : " << x << std::endl;
  if (func)
  {
    func();
  }
}